/*
 * @Author: LVGRAPE
 * @Date: 2023-10-24 09:49:04
 * @LastEditTime: 2023-11-09 00:46:47
 * @LastEditors: LVGRAPE
 * @Description:
 * @FilePath: \ZINO_MCU_SOURCE\ZINO_SRC\bottom_board\soft_spi.c
 * 要啥没啥，爱咋咋的
 */


#include <stdint.h>
// #include "bboard.h"
#include "soft_spi.h"
#include "at32f4xx_gpio.h"
#include "USART_Configuration.h"

#define DBG_TAG "soft_spi"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
 //set bits: GPIOx->BSRE = GPIO_Pin;
 //reset bits: GPIOx->BRE = GPIO_Pin;

#define __io_set(x) bus->ios->x.port->BSRE = bus->ios->x.pin
#define __io_reset(x) bus->ios->x.port->BRE = bus->ios->x.pin
#define __io_read(x) ((bus->ios->x.port->IPTDT & bus->ios->x.pin) != 0)
#define __io_write(x, y) if(y) __io_set(x); else __io_reset(x)

static void spi_delay_us(uint8_t us)
{
    volatile uint32_t len;
    for (; us > 0; us--);
    for (len = 0; len < 1; len++);
}
static uint8_t soft_spi_transfer(struct soft_spi_bus* bus, uint8_t data)
{
#define __write_bit() if (bus->mode & SOFT_SPI_MSB) { __io_write(mosi, (data & 0x80));data <<= 1; } else { __io_write(mosi, (data & 0x01));data >>= 1;}
#define __read_bit() if (__io_read(miso)) { data |= (bus->mode & SOFT_SPI_MSB) ? 0x01 : 0x80; }

// SOFT_SPI_MODE0://CPOL 0, CPHA 0
//     for (int i = 0; i < 8; i++)
//     {
//         __write_bit();
//         __io_write(clk, 1);
//         bus->delay_us(1);
//         __read_bit();
//         __io_write(clk, 0);
//         bus->delay_us(1);
//     }
// SOFT_SPI_MODE1://CPOL 0, CPHA 1
//     for (int i = 0; i < 8; i++)
//     {
//         __io_write(clk, 1);
//         __write_bit();
//         bus->delay_us(1);
//         __io_write(clk, 0);
//         bus->delay_us(1);
//         read_bit();
//     }

// SOFT_SPI_MODE3://CPOL 1, CPHA 0
//     for (int i = 0; i < 8; i++)
//     {
//         __write_bit();
//         __io_write(clk, 0);
//         bus->delay_us(1);
//         __read_bit();
//         __io_write(clk, 1);
//         bus->delay_us(1);
//     }

// SOFT_SPI_MODE4://CPOL 1, CPHA 1
//     for (int i = 0; i < 8; i++)
//     {
//         __io_write(clk, 0);
//         __write_bit();
//         bus->delay_us(1);
//         __io_write(clk, 1);
//         bus->delay_us(1);
//         __read_bit();
//     }
    // __io_write(clk, (bus->mode & SOFT_SPI_CPOL));
    // bus->delay_us(1);
    for (int i = 0; i < 8; i++)
    {
        if(bus->mode&SOFT_SPI_CPHA)
        {
            //NOTE CPHA=1, CPOL=X
            __io_write(clk, !(bus->mode&SOFT_SPI_CPOL));
            __write_bit();
            bus->delay_us(1);
            __io_write(clk, (bus->mode&SOFT_SPI_CPOL));
            bus->delay_us(1);
            __read_bit();
        }
        else
        {
            //NOTE CPHA=0, CPOL=X
            __write_bit();
            __io_write(clk, !(bus->mode&SOFT_SPI_CPOL));
            bus->delay_us(1);
            __read_bit();
            __io_write(clk, (bus->mode&SOFT_SPI_CPOL));
            bus->delay_us(1);
        }
    }

    return data;
}
void soft_spi_bus_send_then_send(struct soft_spi_bus* bus, uint8_t* sbuf1, uint8_t slen1, uint8_t* sbuf2, uint8_t slen2)
{
    //NOTE CS需要取反
    __io_write(clk, bus->mode & SOFT_SPI_CPOL);//空闲电平
    __io_set(cs);
    bus->delay_us(10);
    for (int i = 0; i < slen1; i++)
    {
        bus->ops->transfer(bus, sbuf1[i]);
    }
    for (int i = 0; i < slen2; i++)
    {
        bus->ops->transfer(bus, sbuf2[i]);
    }
    __io_reset(cs);
}
void soft_spi_bus_send_then_receive(struct soft_spi_bus* bus, uint8_t* sbuf, uint8_t slen, uint8_t* rbuf, uint8_t rlen)
{
    //NOTE CS需要取反
    __io_write(clk, bus->mode & SOFT_SPI_CPOL);//空闲电平
    __io_set(cs);
    bus->delay_us(10);
    for (int i = 0; i < slen; i++)
    {
        bus->ops->transfer(bus, sbuf[i]);
    }
    for (int i = 0; i < rlen; i++)
    {
        rbuf[i] = bus->ops->transfer(bus, 0x00);
    }
    __io_reset(cs);

}
struct soft_spi_bus_ops soft_spi_ops = {
    .transfer = soft_spi_transfer,
    .send_then_send = soft_spi_bus_send_then_send,
    .send_then_receive = soft_spi_bus_send_then_receive,
};
void soft_spi_bus_init(struct soft_spi_bus* bus, struct soft_spi_ios* ios)
{
    bus->ios = ios;
    bus->delay_us = spi_delay_us;
    bus->ops = &soft_spi_ops;
    __io_write(clk, bus->mode & SOFT_SPI_CPOL);//空闲电平
    // while (1)
    // {
    //     /* code */
    //     LOG_D("testing mosi pin...");
    //     GPIO_SetBits(bus->ios->mosi.port, bus->ios->mosi.pin);
    //     if (GPIO_ReadInputDataBit(bus->ios->mosi.port, bus->ios->mosi.pin))
    //     {
    //         GPIO_ResetBits(bus->ios->mosi.port, bus->ios->mosi.pin);
    //         if (!GPIO_ReadInputDataBit(bus->ios->mosi.port, bus->ios->mosi.pin))
    //         {
    //             LOG_D("mosi pin is ok");
    //         }
    //     }
    //     else
    //     {
    //         LOG_E("mosi pin is not ok");
    //     }
    // }




    // LOG_D("testing miso pin...");
    // GPIO_SetBits(bus->ios->miso.port, bus->ios->miso.pin);
    // if (GPIO_ReadInputDataBit(bus->ios->miso.port, bus->ios->miso.pin))
    // {
    //     GPIO_ResetBits(bus->ios->miso.port, bus->ios->miso.pin);
    //     if (!GPIO_ReadInputDataBit(bus->ios->miso.port, bus->ios->miso.pin))
    //     {
    //         LOG_D("clk miso is ok");
    //     }
    //     else
    //     {
    //         LOG_E("miso pin is not low");
    //     }
    // }
    // else {
    //     LOG_E("miso pin is not ok high");
    // }
}
